import os
import sys
import importlib.util
import json
from flask import Flask, request, jsonify, send_from_directory
from werkzeug.exceptions import HTTPException
from flask_cors import CORS

from lambda_helper.http_handler import HttpRequest

app = Flask(__name__)
app.config['JSON_AS_ASCII'] = False
app.config['JSONIFY_PRETTYPRINT_REGULAR'] = True

# 启用CORS支持
CORS(app, resources={r"/*": {"origins": "*"}}, 
     allow_headers=['Content-Type', 'Authorization', 'X-Requested-With', 'Cache-Control', 
                   'Pragma', 'Accept', 'Accept-Encoding', 'Accept-Language', 'Connection', 
                   'Host', 'Origin', 'Referer', 'User-Agent', 'X-Forwarded-For', 'X-Real-IP'])

# 设置前端目录路径
FRONTEND_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'client')

# 排除的文件列表
EXCLUDED_FILES = {'main', 'configuration', 'publish'}

def load_lambda_handlers():
    """扫描当前目录下的Python文件，加载lambda_handler函数"""
    handlers = {}
    current_dir = os.path.dirname(os.path.abspath(__file__))
    current_dir = os.path.join(current_dir, 'lambda_functions')
    
    for filename in os.listdir(current_dir):
        if filename.endswith('.py') and not filename.startswith('.'):
            module_name = filename[:-3]  # 去掉.py后缀
            
            # 跳过排除的文件
            if module_name in EXCLUDED_FILES:
                continue
                
            try:
                # 动态导入模块
                spec = importlib.util.spec_from_file_location(module_name, os.path.join(current_dir, filename))
                module = importlib.util.module_from_spec(spec)
                spec.loader.exec_module(module)

                # 检查是否有继承HttpRequest的类
                for name, obj in module.__dict__.items():
                    if isinstance(obj, type) and issubclass(obj, HttpRequest) and obj is not HttpRequest:
                        handlers[module_name] = obj
                        print(f"已加载HttpRequest子类: {module_name}")
                    
            except Exception as e:
                print(f"加载模块 {module_name} 时出错: {e}")
                
    return handlers

# 加载所有Lambda处理器
lambda_handlers = load_lambda_handlers()

def add_cors_headers(response):
    """为响应添加CORS头"""
    response.headers['Access-Control-Allow-Origin'] = '*'
    response.headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, DELETE, PATCH, OPTIONS'
    response.headers['Access-Control-Allow-Headers'] = 'Content-Type, Authorization, X-Requested-With, Cache-Control, Pragma, Accept, Accept-Encoding, Accept-Language, Connection, Host, Origin, Referer, User-Agent, X-Forwarded-For, X-Real-IP'
    return response

def create_lambda_event(flask_request):
    """将Flask请求转换为Lambda事件格式（API Gateway v2）"""
    import time
    import uuid
    
    # 构建API Gateway v2格式的事件
    event = {
        "version": "2.0",
        "routeKey": f"{flask_request.method} {flask_request.path}",
        "rawPath": flask_request.path,
        "rawQueryString": flask_request.query_string.decode('utf-8') if flask_request.query_string else "",
        "headers": dict(flask_request.headers),
        "requestContext": {
            "accountId": "974303038066",
            "apiId": "hzyu2os1rd",
            "domainName": "hzyu2os1rd.execute-api.eu-north-1.amazonaws.com",
            "domainPrefix": "hzyu2os1rd",
            "http": {
                "method": flask_request.method,
                "path": flask_request.path,
                "protocol": "HTTP/1.1",
                "sourceIp": flask_request.remote_addr,
                "userAgent": flask_request.headers.get('User-Agent', '')
            },
            "requestId": str(uuid.uuid4()).replace('-', '')[:16],
            "routeKey": f"{flask_request.method} {flask_request.path}",
            "stage": "$default",
            "time": time.strftime("%d/%b/%Y:%H:%M:%S +0000", time.gmtime()),
            "timeEpoch": int(time.time() * 1000)
        },
        "isBase64Encoded": False
    }
    
    # 处理请求体
    if flask_request.method in ['POST', 'PUT', 'PATCH'] and flask_request.is_json:
        try:
            event['body'] = json.dumps(flask_request.get_json())
            event['headers']['Content-Type'] = 'application/json'
        except Exception:
            # 如果JSON解析失败，使用原始数据
            event['body'] = flask_request.data.decode('utf-8') if flask_request.data else None
    elif flask_request.data:
        event['body'] = flask_request.data.decode('utf-8')
    
    # 处理查询参数
    if flask_request.args:
        event['queryStringParameters'] = dict(flask_request.args)
    
    return event

def create_lambda_context():
    """创建Lambda上下文对象"""
    class LambdaContext:
        def __init__(self):
            self.function_name = "local_lambda"
            self.function_version = "$LATEST"
            self.invoked_function_arn = "arn:aws:lambda:local:123456789012:function:local_lambda"
            self.memory_limit_in_mb = 128
            self.remaining_time_in_millis = lambda: 30000
            self.aws_request_id = "local-request-id"
            self.log_group_name = "/aws/lambda/local_lambda"
            self.log_stream_name = "local-log-stream"
    
    return LambdaContext()

@app.route('/', methods=['GET'])
def serve_index():
    """返回前端index.html"""
    return send_from_directory(FRONTEND_DIR, 'index.html')

@app.route('/<path:filename>')
def serve_static(filename):
    """返回静态文件"""
    return send_from_directory(FRONTEND_DIR, filename)

@app.route('/api/v1/functions', methods=['GET'])
def get_functions():
    """获取所有可用的Lambda函数"""
    return jsonify({
        'functions': list(lambda_handlers.keys())
    })

@app.route('/api/v1/history', methods=['GET'])
def get_history():
    """获取请求历史"""
    # 这里可以添加从数据库或文件读取历史记录的逻辑
    return jsonify({'history': []})

@app.route('/api/v1/<function_name>', methods=['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS'])
def lambda_endpoint(function_name):
    """Lambda函数端点"""
    # 处理OPTIONS请求（预检请求）
    if request.method == 'OPTIONS':
        response = app.response_class()
        response.headers['Access-Control-Allow-Origin'] = '*'
        response.headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, DELETE, PATCH, OPTIONS'
        response.headers['Access-Control-Allow-Headers'] = 'Content-Type, Authorization, X-Requested-With, Cache-Control, Pragma, Accept, Accept-Encoding, Accept-Language, Connection, Host, Origin, Referer, User-Agent, X-Forwarded-For, X-Real-IP'
        response.headers['Access-Control-Max-Age'] = '86400'
        return response, 200
    
    if function_name not in lambda_handlers:
        response = jsonify({'error': f'Lambda函数 {function_name} 未找到'})
        response.headers['Content-Type'] = 'application/json; charset=utf-8'
        response = add_cors_headers(response)
        return response, 404
    
    try:
        # 创建Lambda事件和上下文
        event = create_lambda_event(request)
        context = create_lambda_context()
        
        # 自动获取继承HttpRequest的类
        if isinstance(lambda_handlers[function_name], type) and issubclass(lambda_handlers[function_name], HttpRequest):
            result = lambda_handlers[function_name](event, context).handle()
        
        # 处理返回结果
        if isinstance(result, dict):
            status_code = result.get('statusCode', 200)
            body = result.get('body', '')
            
            # 尝试解析body为JSON
            try:
                if isinstance(body, str):
                    body_json = json.loads(body)
                    response = jsonify(body_json)
                    response.headers['Content-Type'] = 'application/json; charset=utf-8'
                    response = add_cors_headers(response)
                    return response, status_code
                else:
                    response = jsonify(body)
                    response.headers['Content-Type'] = 'application/json; charset=utf-8'
                    response = add_cors_headers(response)
                    return response, status_code
            except (json.JSONDecodeError, TypeError):
                # 如果不是JSON，返回字符串
                response = app.response_class(
                    response=body,
                    status=status_code,
                    mimetype='text/plain; charset=utf-8'
                )
                response = add_cors_headers(response)
                return response
        else:
            # 如果不是字典，直接返回
            response = app.response_class(
                response=str(result),
                status=200,
                mimetype='text/plain; charset=utf-8'
            )
            response = add_cors_headers(response)
            return response
            
    except Exception as e:
        print(f"执行Lambda函数 {function_name} 时出错: {e}")
        response = jsonify({'error': str(e)})
        response.headers['Content-Type'] = 'application/json; charset=utf-8'
        response = add_cors_headers(response)
        return response, 500

@app.errorhandler(HTTPException)
def handle_exception(e):
    """处理HTTP异常"""
    response = jsonify({
        'error': e.description,
        'code': e.code
    })
    response.headers['Content-Type'] = 'application/json; charset=utf-8'
    response = add_cors_headers(response)
    return response, e.code

if __name__ == '__main__':
    print("Lambda本地测试服务器启动中...")
    print(f"已加载的Lambda函数: {list(lambda_handlers.keys())}")
    print("访问 http://localhost:5476 查看前端界面")
    print("API端点运行在 http://localhost:5476/api")
    
    app.run(host='0.0.0.0', port=5476, debug=True)